/*
 * @Description: 封装手动上传钩子为异步函数
 * @Author: HuiSir<https://gitee.com/huisir00>
 * @Date: 2025-08-05 18:20:37
 * @LastEditTime: 2025-09-17 11:34:22
 */
import { ref, watch, Ref } from "vue";
import {
  ElMessage,
  UploadInstance,
  UploadUserFile,
  UploadFile,
  UploadStatus,
} from "element-plus";
import { UploadSubmitResult } from "../types";

export const usePromiseSubmit = (
  uploadRef: Ref<UploadInstance | undefined>,
  uploadFilesList: Ref<UploadUserFile[]>
) => {
  // 存储每个文件的Promise控制器
  const uploadPromises = ref<
    Record<
      number,
      { resolve: (value: unknown) => void; reject: () => void } | null
    >
  >({});
  // 文件状态跟踪器
  const fileStatusMap = ref<Record<number, UploadStatus>>({});
  // 上传结果集合
  const results = ref<{ uid: number; response: Record<string, unknown> }[]>([]);

  // 初始化文件状态跟踪
  const initFileTracker = () => {
    fileStatusMap.value = {};
    uploadPromises.value = {};

    uploadFilesList.value.forEach((file) => {
      const uid = file.uid;
      if (!uid || file.status === "success") return;
      fileStatusMap.value[uid] = "ready"; // 初始状态
      uploadPromises.value[uid] = null; // 初始化Promise
    });
  };

  // 为单个文件创建Promise
  const createFilePromise = (uid: number) => {
    return new Promise((resolve, reject) => {
      // 存储控制器
      uploadPromises.value[uid] = { resolve, reject };

      if (fileStatusMap.value[uid] === "success") {
        resolve({ uid, status: "success" });
        return;
      }

      // 超时处理（15秒）
      const timeoutId = setTimeout(() => {
        const message = `文件上传超时 (UID: ${uid})`;
        ElMessage.error(message);
        reject({ uid, message });
      }, 15000);

      // 监听状态变化
      watch(
        () => fileStatusMap.value[uid],
        (status) => {
          if (status === "success") {
            clearTimeout(timeoutId);
            resolve({ uid, status });
          } else if (status === "fail") {
            clearTimeout(timeoutId);
            const message = `上传失败 (UID: ${uid})`;
            ElMessage.error(message);
            reject({ uid, message });
          }
        }
      );
    });
  };

  // 事件封装
  const onChange = (file: UploadFile) => {
    if (file.status === "success" || file.status === "fail") {
      fileStatusMap.value[file.uid] = file.status;
      if (file.status === "success") {
        results.value.push({
          uid: file.uid,
          response: file.response as Record<string, unknown>,
        });
      }
    }
  };

  // 封装submit为Promise
  const promiseSubmit = () => {
    return new Promise((resolve, reject) => {
      // 重置状态
      results.value = [];
      initFileTracker();

      // 创建所有文件的Promise
      const promiseArr = Object.keys(fileStatusMap.value).map((uid) =>
        createFilePromise(Number(uid))
      );

      // 已全部上传或无文件时阻塞submit，避免已上传的文件再次上传
      if (!promiseArr?.length) {
        resolve([]);
        return;
      }

      // 执行上传
      uploadRef.value!.submit();

      // 等待所有文件完成
      Promise.allSettled(promiseArr)
        .then((responses) => {
          // 返回结构化结果
          const formattedResults = responses.map(
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            (res: any): UploadSubmitResult => ({
              status: res.status,
              uid: res.value?.uid || res.reason?.uid,
              response:
                res.status === "fulfilled"
                  ? results.value.find((r) => r.uid === res.value?.uid)
                      ?.response
                  : res.reason.message,
            })
          );

          resolve(formattedResults);
        })
        .catch(reject);
    });
  };

  return { onChange, promiseSubmit };
};
